package com.marvels.financial.loan.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import cn.hutool.json.JSONUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.util.StringUtil;
import com.marvels.common.constants.ExtensionFunctionEnum;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.constants.RedisKeyConstant;
import com.marvels.common.dto.UserDTO;
import com.marvels.common.dto.pay.MarvelsPayResultDTO;
import com.marvels.common.dto.pay.McfePaymentUserBindCard;
import com.marvels.common.dto.pay.McfeRepaymentTradeDetails;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.CommonProperties;
import com.marvels.common.utils.GenerateReqNoUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.ServerProperties;
import com.marvels.financial.collection.dao.OverdueCollectTaskDao;
import com.marvels.financial.loan.dao.McfeCustomerLoanContractDao;
import com.marvels.financial.loan.dao.McfeCustomerRepaymentPlanDao;
import com.marvels.financial.loan.dao.McfeLendingProcessDao;
import com.marvels.financial.loan.dao.McfePaymentWithholdDao;
import com.marvels.financial.loan.dao.McfePaymentWithholdDetailDao;
import com.marvels.financial.loan.dao.McfeRepaymentFlowDao;
import com.marvels.financial.loan.dto.HandWithholdConditionDTO;
import com.marvels.financial.loan.dto.HandWithholdListDTO;
import com.marvels.financial.loan.dto.HandleWithholePaymentDTO;
import com.marvels.financial.loan.dto.McfeCustomerLoanContractDTO;
import com.marvels.financial.loan.dto.McfeCustomerRepaymentPlanDTO;
import com.marvels.financial.loan.dto.McfeLendingProcess;
import com.marvels.financial.loan.dto.McfePaymentWithholdDTO;
import com.marvels.financial.loan.dto.McfePaymentWithholdDetailDTO;
import com.marvels.financial.loan.dto.McfeRepaymentFlowDTO;
import com.marvels.financial.loan.dto.PaymentResponse;
import com.marvels.financial.loan.dto.PaymentResponse.SingleResult;
import com.marvels.financial.loan.dto.WithholeQueryConditionDTO;
import com.marvels.financial.loan.service.HandleWithholdApi;
import com.marvels.financial.loan.service.WithholdPaymentApi;
import com.marvels.financial.pay.dao.McfePaymentUserBindCardMapper;
import com.marvels.financial.pay.dto.WithholdConditionDTO;
import com.marvels.financial.pay.service.PayService;

import net.sf.json.JSONObject;

@Service
public class WithholdPaymentImpl implements WithholdPaymentApi {


	@Autowired
	private McfeCustomerRepaymentPlanDao mcfeCustomerRepaymentPlanDao;

	@Value("${config.properties.path}")
	private  String configPropertiesPath;


	@Autowired
	private McfePaymentWithholdDetailDao withholdDetailDao;

	@Autowired
	private McfeCustomerLoanContractDao mcfeCustomerLoanContractDao;

	@Autowired
	private McfePaymentWithholdDetailDao detailDao;

	@Autowired
	private McfeRepaymentFlowDao flowDao;

	@Autowired
	private McfePaymentWithholdDao withholdDao;

	@Autowired
	private HandleWithholdApi handleWithholdApi;

	@Autowired
	private McfeRepaymentFlowDao mcfeRepaymentFlowDao;

	@Autowired
	private PayService payService;

	@Autowired
	private McfeLendingProcessDao mcfeLendingProcessDao;

	@Autowired
	private McfePaymentUserBindCardMapper mcamPaymentUserBindCardMapper;

	@Autowired
	private OverdueCollectTaskDao overdueCollectTaskDao;

	@Override
	public PaymentResponse withholdPayment(HandleWithholePaymentDTO conditionDto){
		PaymentResponse paymentResponse = new PaymentResponse();
		if (StringUtils.isEmpty(conditionDto.getFundSource())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("资金源不能为空");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getMerchantTreatyNo())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("用户id不能为空");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getReqNo())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("请求编号不能为空");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getCustName())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("姓名不能为空");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getBankName())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("银行名称不能为空");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getCustBankAccountNo())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("银行卡号不能为空");
			return paymentResponse;
		}

		if (conditionDto.getAmount() == null) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("交易金额不能为空");
			return paymentResponse;
		}

		if (conditionDto.getAmount().compareTo(new BigDecimal("0")) < 1) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("交易金额不能为0");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getRemark())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("备注不能为空");
			return paymentResponse;
		}
		if (StringUtils.isEmpty(conditionDto.getCustBindPhoneNo())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("手机号码不能为空");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getCustBankAcctType())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("客户银行卡类型不能为空");
			return paymentResponse;
		}

		if (StringUtils.isEmpty(conditionDto.getCustId())) {
			paymentResponse.setCode("-1");
			paymentResponse.setMsg("身份证号码不能为空");
			return paymentResponse;
		}
		BigDecimal amount = conditionDto.getAmount().setScale(2, BigDecimal.ROUND_HALF_UP);
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>>loanId:" + conditionDto.getLoanId() + ",身份证:" + conditionDto.getCustId() + ",银行卡号:"
				+ conditionDto.getCustBankAccountNo() + ",代扣请求参数:" + conditionDto);
		MarvelsPayResultDTO marvelsResultDTO=null;
		String paymentChannel="";
		if(StringUtils.isNotEmpty(conditionDto.getPaymentChannel())){
			paymentChannel=conditionDto.getPaymentChannel();
		}else{
			paymentChannel=ServerProperties.getValue(configPropertiesPath, "common.properties", "payment_channel");
		}
		WithholdConditionDTO dto=new WithholdConditionDTO();
		dto.setRequestNo(conditionDto.getReqNo());
		dto.setIdno(conditionDto.getCustId());
		dto.setBindCard(conditionDto.getCustBankAccountNo());
		dto.setAmount(amount.toString());
		dto.setTitle("还款代扣");
		dto.setChannel(paymentChannel);
		dto.setType(conditionDto.getType());
		dto.setBankName(conditionDto.getBankName());
		dto.setCustName(conditionDto.getCustName());
		dto.setMobile(conditionDto.getCustBindPhoneNo());
		dto.setT2SmsCode(conditionDto.getT2SmsCode());
		dto.setLoanId(conditionDto.getLoanId());
		dto.setPayType(conditionDto.getPayType());
		try {
			marvelsResultDTO = payService.withhold(dto);
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>>>>>>>>>loanId:" + conditionDto.getLoanId() + ",身份证:" + conditionDto.getCustId() + ",银行卡号:"
					+ conditionDto.getCustBankAccountNo() + ",第三方代扣异常" ,e);
		}
		MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>>>loanId:" + conditionDto.getLoanId() + ",身份证:" + conditionDto.getCustId() + ",银行卡号:"
				+ conditionDto.getCustBankAccountNo() + ",走第三方代扣返回参数:" + JSONUtil.toJsonStr(marvelsResultDTO));

	    String status = "";
		String rtnOrderNo = "";// 第三方返回订单号
		String rtnResponseCode = "";// 扣款返回码
		String rtnResponseMsg = "";// 扣款返回信息
		BigDecimal successAmount = BigDecimal.valueOf(0);
		PaymentResponse paymentResponseReturn = new PaymentResponse();
		paymentResponseReturn.setChannel(paymentChannel);
		if (null == marvelsResultDTO) {
			status = MarvelsConstant.FAILED;
			rtnResponseMsg = "返回信息为空";
		} else {
			rtnResponseMsg = marvelsResultDTO.getMessage();
			rtnResponseCode = marvelsResultDTO.getCode();
			if ("0".equals(rtnResponseCode)) {
				McfeRepaymentTradeDetails mcamRepaymentTradeDetails = (McfeRepaymentTradeDetails)marvelsResultDTO.getData();
				//代扣状态
				if(mcamRepaymentTradeDetails != null){
					String returnStatus = mcamRepaymentTradeDetails.getResult();
					rtnOrderNo = mcamRepaymentTradeDetails.getPayOrderNumber();
					paymentResponseReturn.setOrderNumber(rtnOrderNo);
					if("0".equals(returnStatus)){
						// 成功
						status = MarvelsConstant.SUCCESS;
						successAmount = conditionDto.getAmount();
						paymentResponseReturn.setSuccessAmount(successAmount);
					}else if("-1".equals(returnStatus)){
						//失败
						status = MarvelsConstant.FAILED;
						rtnResponseMsg = mcamRepaymentTradeDetails.getErrorMsg();
					}else{
						//其余，做代扣中处理
						status = MarvelsConstant.PROCESSING;
						rtnResponseMsg = mcamRepaymentTradeDetails.getErrorMsg();
					}
				}else{
					//按理不会进入这个逻辑
					status = MarvelsConstant.FAILED;
					rtnResponseMsg = "返回代扣信息为空";
				}


			}else{
				//做代扣中处理
				status = MarvelsConstant.FAILED;
			}
		}

		paymentResponseReturn.setCode(status);
		paymentResponseReturn.setMsg(rtnResponseMsg);
		paymentResponseReturn.setSuccessAmount(successAmount);
		paymentResponseReturn.setChannel(paymentChannel);

		return paymentResponseReturn;
	}

	@Override
	public PaymentResponse withholdPaymentQuery(WithholeQueryConditionDTO dto) {
		String paymenChannel  = ServerProperties.getValue(configPropertiesPath, "common.properties", "payment_channel");
		MarvelsPayResultDTO marvelsResultDTO = payService.queryWithholdResult(dto.getOrderNumber(),paymenChannel, dto.getPayType());
		String status = "";
		String rtnOrderNo = "";// 第三方返回订单号
		String rtnResponseCode = "";// 扣款返回码
		String rtnResponseMsg = "";// 扣款返回信息
		BigDecimal successAmount = BigDecimal.valueOf(0);
		PaymentResponse paymentResponseReturn = new PaymentResponse();
		if (null == marvelsResultDTO) {
			status = MarvelsConstant.PROCESSING;
			rtnResponseMsg = "返回信息为空";
		} else {
			rtnResponseMsg = marvelsResultDTO.getMessage();
			rtnResponseCode = marvelsResultDTO.getCode();
			if ("0".equals(rtnResponseCode)) {
				McfeRepaymentTradeDetails mcamRepaymentTradeDetails = (McfeRepaymentTradeDetails)marvelsResultDTO.getData();
				//代扣状态
				if(mcamRepaymentTradeDetails != null){
					paymentResponseReturn.setChannel(mcamRepaymentTradeDetails.getChannel());
					String returnStatus = mcamRepaymentTradeDetails.getResult();
					rtnOrderNo = mcamRepaymentTradeDetails.getPayOrderNumber();
					if("0".equals(returnStatus)){
						// 成功
						status = MarvelsConstant.SUCCESS;
						paymentResponseReturn.setOrderNumber(rtnOrderNo);
						String amount = mcamRepaymentTradeDetails.getAmount();
						if(StringUtils.isNotEmpty(amount)){
							successAmount = BigDecimal.valueOf(Double.valueOf(amount));
						}
						paymentResponseReturn.setSuccessAmount(successAmount);
					}else if("-1".equals(returnStatus) || "-3".equals(returnStatus)){
						//失败
						status = MarvelsConstant.FAILED;
						rtnResponseMsg = "代扣失败";
					}else{
						//其余，做代扣中处理
						status = MarvelsConstant.PROCESSING;
						rtnResponseMsg = "代扣中";
					}
				}


			}else{
				//做代扣中处理
				status = MarvelsConstant.PROCESSING;
				rtnResponseMsg = "代扣中";
			}
		}

		paymentResponseReturn.setCode(status);
		paymentResponseReturn.setMsg(rtnResponseMsg);
		paymentResponseReturn.setSuccessAmount(successAmount);
		return paymentResponseReturn;
	}



	/**
	 *
	* @Title: withholdCommonDeal
	* @Description:扣款公用接口(非提前结清)
	* @param paymentWithholdDTO
	* @return
	* @throws MarvelsBusinessException
	* @author 李瑶
	* @date 2018年10月20日 下午2:03:17
	 */
	@Override
	public PaymentResponse withholdCommonDeal(McfePaymentWithholdDTO paymentWithholdDTO) throws MarvelsBusinessException{
		MarvelsLogUtil.getInstance().info(">>>>>>>>扣款请求参数:" + JSONObject.fromObject(paymentWithholdDTO));
		String loanId=paymentWithholdDTO.getLoanId();
		if(StringUtils.isEmpty(loanId)){
			throw new MarvelsBusinessException("loanId不能为空");
		}
		if(paymentWithholdDTO.getAmount()==null || paymentWithholdDTO.getAmount().compareTo(BigDecimal.ZERO)<1){
			throw new MarvelsBusinessException("金额必须大于0");
		}
		if(StringUtils.isEmpty(paymentWithholdDTO.getBankCardNo())){
			throw new MarvelsBusinessException("银行卡号不能为空");
		}
		if(StringUtils.isEmpty(paymentWithholdDTO.getBankName())){
			throw new MarvelsBusinessException("银行名称不能为空");
		}
		if(StringUtils.isEmpty(paymentWithholdDTO.getCustCardNo())){
			throw new MarvelsBusinessException("身份证号不能为空");
		}
		if(StringUtils.isEmpty(paymentWithholdDTO.getTransctionSeq())){
			throw new MarvelsBusinessException("请求编号不能为空");
		}
		String withholdCategory=paymentWithholdDTO.getWithholdCategory();
		if(StringUtils.isEmpty(withholdCategory) || (StringUtils.isNotEmpty(withholdCategory) && withholdCategory.equals("1"))){
			if(StringUtils.isEmpty(paymentWithholdDTO.getRepayStyle())){
				throw new MarvelsBusinessException("还款方式不能为空");
			}
			if(StringUtils.isEmpty(paymentWithholdDTO.getFlowPayType()) ){
				throw new MarvelsBusinessException("还款类型不能为空");
			}
		}
		if(StringUtils.isNotEmpty(withholdCategory) && withholdCategory.equals("2")){
			if(paymentWithholdDTO.getExtensionDay()==null){
				throw new MarvelsBusinessException("展期天数不能为空");
			}
		}
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				// 先将这个key设置过期时间
				CacheUtils.setExpire(key, 60);
				McfeCustomerLoanContractDTO contractDTO = mcfeCustomerLoanContractDao.selectContractByLoanId(loanId);
				if (null == contractDTO) {
					throw new MarvelsBusinessException("合同信息不存在");
				}
				if (2==contractDTO.getStatus() || 3==contractDTO.getStatus()
						|| 10==contractDTO.getStatus()) {
					throw new MarvelsBusinessException("进件不处于还款状态");
				}
				String type=paymentWithholdDTO.getType();
				/*
				 * //不是直接代扣则同步绑卡信息
				 * if(!"1".equals(type)){
					//同步合同信息
					synchronizedBankCard(contractDTO, null);
				}*/
				// 判断还款计划对应的进件是否有处在交易中的代扣
				McfePaymentWithholdDetailDTO detailDTO = detailDao.selectTradingByLoanId(loanId);
				if (detailDTO != null) {
					MarvelsLogUtil.getInstance().info(">>>>>>>>>>loanId:" + loanId + ",有处在交易中的代扣");
					throw new MarvelsBusinessException("存在处理中的代扣,请稍候再试");
				}
				// 判断还款计划对应的进件是否有处在正在冲账中的流水
				McfeRepaymentFlowDTO flowDTO = flowDao.selectDealingByLoanId(loanId);
				if (flowDTO != null) {
					MarvelsLogUtil.getInstance().info(">>>>>>>>>>loanId:" + loanId + ",有处在冲账中或未冲账的流水");
					throw new MarvelsBusinessException("存在未冲账的流水,请稍候再试");
				}
				// 拆分金额
				BigDecimal[] splitAmount = handleWithholdApi.amountSplit(paymentWithholdDTO.getAmount(), paymentWithholdDTO.getBankHeadLink());
				if (null == splitAmount || splitAmount.length < 1) {
					splitAmount = new BigDecimal[] { paymentWithholdDTO.getAmount() };
				}
				UserDTO user = null;
				try {
					user=CacheUtils.getCacheUser();
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>获取本地用户信息失败");
				}
				String userCode=user==null?"system":user.getUserCode();
				// 插入代扣总记录
				paymentWithholdDTO.setChannelCode(contractDTO.getChannelCode());
				paymentWithholdDTO.setChannelName(contractDTO.getChannelName());
				paymentWithholdDTO.setCreatedBy(userCode);
				paymentWithholdDTO.setCreatedDate(new Date());
				if(!"1".equals(type)){
					paymentWithholdDTO.setCustName(contractDTO.getCustName());
				}
				paymentWithholdDTO.setFundCode(contractDTO.getFundCode());
				paymentWithholdDTO.setFundName(contractDTO.getFundName());
				paymentWithholdDTO.setLoanId(contractDTO.getLoanId());
				paymentWithholdDTO.setPayCount(splitAmount.length);
				paymentWithholdDTO.setPayType(StringUtils.isEmpty(paymentWithholdDTO.getRepayStyle())?4:Integer.parseInt(paymentWithholdDTO.getRepayStyle()));// 还款类型: 1-自动代扣;2-当前还款;3-提前结清;4-自定义还款;5-下期还款; 6-手动代扣 ; 9-支付宝还款 10-支付宝提前结清' 100转账支付
				paymentWithholdDTO.setProductCode(contractDTO.getProductCode());
				paymentWithholdDTO.setProductName(contractDTO.getProductName());
				paymentWithholdDTO.setProductType(contractDTO.getProductType());
				paymentWithholdDTO.setProductTypeName(contractDTO.getProductTypeName());
				paymentWithholdDTO.setStatus("2");// 代扣中
				paymentWithholdDTO.setUpdatedBy(userCode);
				paymentWithholdDTO.setUpdatedDate(new Date());
				paymentWithholdDTO.setWithholdCode(paymentWithholdDTO.getTransctionSeq());
				int count = withholdDao.insertSelective(paymentWithholdDTO);
				if (count < 1) {
					throw new MarvelsBusinessException("持久化代扣申请失败");
				}
				BigDecimal succcessAmount = new BigDecimal("0.00");
				// 将金额循环支付
				PaymentResponse totalResponse=new PaymentResponse();
				List<SingleResult> singleResults=new ArrayList<SingleResult>();
				String rtnResponseMsg = "";// 扣款返回信息
				for (int i = 0; i < splitAmount.length; i++) {
					// 持久化代扣流水
					String reqNo = GenerateReqNoUtils.transctionReq("TX");
					detailDTO = new McfePaymentWithholdDetailDTO();
					detailDTO.setAmount(splitAmount[i]);
					detailDTO.setBankHeadLink(paymentWithholdDTO.getBankHeadLink());
					detailDTO.setChannelCode(contractDTO.getChannelCode());
					detailDTO.setChannelName(contractDTO.getChannelName());
					detailDTO.setExtensionDay(paymentWithholdDTO.getExtensionDay());
					detailDTO.setWithholdCategory(paymentWithholdDTO.getWithholdCategory());
					detailDTO.setCreatedBy(userCode);
					detailDTO.setCreatedDate(new Date());
					detailDTO.setFundCode(contractDTO.getFundCode());
					detailDTO.setFundName(contractDTO.getFundName());
					detailDTO.setLoanId(contractDTO.getLoanId());
					detailDTO.setPayType(StringUtils.isEmpty(paymentWithholdDTO.getRepayStyle())?"11":paymentWithholdDTO.getRepayStyle());
					detailDTO.setProductCode(contractDTO.getProductCode());
					detailDTO.setProductName(contractDTO.getProductName());
					detailDTO.setProductType(contractDTO.getProductType());
					detailDTO.setProductTypeName(contractDTO.getProductTypeName());
					if(StringUtils.isNotEmpty(paymentWithholdDTO.getReqChannel())){
						detailDTO.setReqChannel(paymentWithholdDTO.getReqChannel());
					}
					detailDTO.setStatus("1");// 交易中
					detailDTO.setTranctionDate(new Date());
					detailDTO.setTransctionSeq(reqNo);
					detailDTO.setUpdatedBy(userCode);
					detailDTO.setUpdatedDate(new Date());
					detailDTO.setWithholdCode(paymentWithholdDTO.getTransctionSeq());

					detailDTO.setBankName(paymentWithholdDTO.getBankName());
					detailDTO.setBankCardNo(paymentWithholdDTO.getBankCardNo());
					detailDTO.setCustCardNo(paymentWithholdDTO.getCustCardNo());
					detailDTO.setCustName(paymentWithholdDTO.getCustName());
					detailDTO.setMobile(paymentWithholdDTO.getMobile() == null ? contractDTO.getMobile() : paymentWithholdDTO.getMobile());
					detailDTO.setBatchStatus("1");//初始化为处理中，不然查结果和主动代扣会冲突
					/*if("1".equals(type)){
						detailDTO.setBankName(paymentWithholdDTO.getBankName());
						detailDTO.setBankCardNo(paymentWithholdDTO.getBankCardNo());
						detailDTO.setCustCardNo(paymentWithholdDTO.getCustCardNo());
						detailDTO.setCustName(paymentWithholdDTO.getCustName());
						detailDTO.setMobile(paymentWithholdDTO.getMobile());
					}else{
						detailDTO.setBankName(contractDTO.getPaymentBankName());
						detailDTO.setBankCardNo(contractDTO.getPaymentAcctNo());
						detailDTO.setCustCardNo(contractDTO.getCustCardNo());
						detailDTO.setCustName(contractDTO.getCustName());
						detailDTO.setMobile(contractDTO.getMobile());
					}*/
					int detailCount = withholdDetailDao.insertSelective(detailDTO);
					if (detailCount < 1) {
						continue;
					}
					// 发起代扣
					HandleWithholePaymentDTO paymentDTO = new HandleWithholePaymentDTO();
					paymentDTO.setType(type);
					paymentDTO.setAmount(splitAmount[i]);
					paymentDTO.setCustBankAcctType("1");
					paymentDTO.setFundSource(contractDTO.getFundCode());
					paymentDTO.setLoanId(contractDTO.getLoanId());
					paymentDTO.setMerchantTreatyNo(contractDTO.getLoanId());

					paymentDTO.setBankName(paymentWithholdDTO.getBankName());
					paymentDTO.setCustBankAccountNo(paymentWithholdDTO.getBankCardNo());
					paymentDTO.setCustBindPhoneNo(paymentWithholdDTO.getMobile() == null ? contractDTO.getMobile() : paymentWithholdDTO.getMobile());
					paymentDTO.setCustId(paymentWithholdDTO.getCustCardNo());
					paymentDTO.setCustName(paymentWithholdDTO.getCustName());
					if("1".equals(type)){
						paymentDTO.setT2SmsCode(paymentWithholdDTO.getT2SmsCode());
					}
					/*else{
						paymentDTO.setBankName(contractDTO.getPaymentBankName());
						paymentDTO.setCustBankAccountNo(contractDTO.getPaymentAcctNo());
						paymentDTO.setCustBindPhoneNo(contractDTO.getMobile());
						paymentDTO.setCustId(contractDTO.getCustCardNo());
						paymentDTO.setCustName(contractDTO.getCustName());
					}*/
					if(StringUtils.isNotEmpty(paymentWithholdDTO.getReqChannel())){
						paymentDTO.setPaymentChannel(paymentWithholdDTO.getReqChannel());
					}
					paymentDTO.setRemark("代扣");
					paymentDTO.setReqNo(reqNo);
					paymentDTO.setPayType(paymentWithholdDTO.getPayType());
					PaymentResponse paymentResponse = null;
					MarvelsLogUtil.getInstance().info(">>>>>>>>手动代扣发起代扣交易请求参数:" + JSONObject.fromObject(paymentDTO));
					try {
						paymentResponse = withholdPayment(paymentDTO);
					} catch (Exception e) {
						MarvelsLogUtil.getInstance().error(">>>>>>>>手动代扣发起代扣交易异常:", e);
					}
					MarvelsLogUtil.getInstance()
							.info(">>>>>>>>手动代扣发起代扣交易返回参数:" + JSONObject.fromObject(paymentResponse));
					String status = "";// ；1交易中; 2代扣成功 9代扣失败
					String rtnOrderNo = "";// 第三方返回订单号
					String rtnResponseCode = "";// 扣款返回码

					BigDecimal amountAct = new BigDecimal("0");// 实际成功金额
					String resChannel = null;
					if (null == paymentResponse) {
						status = "1";
						rtnResponseMsg = "返回信息为空";
					} else {
						resChannel = paymentResponse.getChannel();
						rtnResponseMsg = paymentResponse.getMsg();
						rtnOrderNo = paymentResponse.getOrderNumber();
						rtnResponseCode = paymentResponse.getCode();
						if ("0".equals(paymentResponse.getCode())) {// 成功
							status = "2";
							amountAct = splitAmount[i];
							succcessAmount = succcessAmount.add(amountAct);
						}else if(MarvelsConstant.FAILED.equals(paymentResponse.getCode())){//失败
							status = "9";
						}else {// 其余做处理中处理
							status = "1";
						}
						SingleResult singleResult=new PaymentResponse().new SingleResult();
						singleResult.setErrorCode(paymentResponse.getCode());
						singleResult.setErrorMsg(paymentResponse.getMsg());
						singleResults.add(singleResult);
					}
					// 更新代扣流水
					McfePaymentWithholdDetailDTO detailDTOUpdate = new McfePaymentWithholdDetailDTO();
					detailDTOUpdate.setId(detailDTO.getId());
					detailDTOUpdate.setUpdatedBy(userCode);
					detailDTOUpdate.setUpdatedDate(new Date());
					detailDTOUpdate.setAmountAct(amountAct);
					detailDTOUpdate.setStatus(status);// ；1交易中; 2代扣成功 9代扣失败
					detailDTOUpdate.setRtnOrderNo(rtnOrderNo);
					// 001 快付通（云科贷） ,002 宝付（云科贷） 003 宝付（口袋） 004 宝付（渤海） 005 支付宝  006 运营

					detailDTOUpdate.setResChannel(resChannel);
					detailDTOUpdate.setRtnResponseDate(new Date());
					detailDTOUpdate.setRtnResponseCode(rtnResponseCode);// 扣款返回码
					detailDTOUpdate.setRtnResponseMsg(rtnResponseMsg);// 扣款返回信息
					detailDTOUpdate.setBatchStatus("2");//置为处理完成
					withholdDetailDao.updateByPrimaryKeySelective(detailDTOUpdate);
					if ("2".equals(status)) {// 成功
						detailDTOUpdate.setTransctionSeq(reqNo);
						withholdSuccess(contractDTO,paymentWithholdDTO,detailDTOUpdate);
					}
				}
				// 更新代扣总记录
				McfePaymentWithholdDTO withholdDTOUpdate = new McfePaymentWithholdDTO();
				withholdDTOUpdate.setId(paymentWithholdDTO.getId());
				if (paymentWithholdDTO.getAmount().compareTo(succcessAmount) == 0) {
					withholdDTOUpdate.setStatus("0");// 代扣成功
					totalResponse.setSuccessAmount(succcessAmount);
					totalResponse.setCode("0");
					totalResponse.setMsg("成功");
				} else {
					withholdDTOUpdate.setStatus("2");//处理中
					totalResponse.setCode("1");
					totalResponse.setMsg(rtnResponseMsg);
				}
				withholdDTOUpdate.setAmountAct(succcessAmount);
				withholdDTOUpdate.setUpdatedBy(userCode);
				withholdDTOUpdate.setUpdatedDate(new Date());
				withholdDao.updateByPrimaryKeySelective(withholdDTOUpdate);
				totalResponse.setList(singleResults);
				return totalResponse;
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",代扣通用方法代扣异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
		return null;
	}



	/**
	 * 展期费代扣成功处理
	 * @param withholdDTO
	 * @return
	 */
	public void extensionwithholdeSuccess(McfePaymentWithholdDTO withholdDTO) throws MarvelsBusinessException{
		extensionwithholdeSuccess(withholdDTO.getLoanId(),withholdDTO.getAmount(),withholdDTO.getExtensionDay());
	}

	/**
	 * 展期费冲账
	 * @param loanId
	 * @param amount
	 * @param extensionDay
	 * @throws MarvelsBusinessException
	 */
	public void extensionwithholdeSuccess(String loanId, BigDecimal amount,int extensionDay) throws MarvelsBusinessException{
		// 查询合同状态
		McfeCustomerLoanContractDTO contractDTO = mcfeCustomerLoanContractDao.selectContractByLoanId(loanId);
		if(contractDTO==null){
			throw new MarvelsBusinessException("合同信息不存在");
		}
		Calendar calendar=Calendar.getInstance();
		//查询还款计划
		List<McfeCustomerRepaymentPlanDTO> planList=mcfeCustomerRepaymentPlanDao.selectAllPlan(loanId);
		if(planList==null || planList.size()<1){
			throw new MarvelsBusinessException("还款计划不存在");
		}
		McfeCustomerRepaymentPlanDTO planDTO=planList.get(0);//只有一条还款计划
		if(contractDTO.getStatus()==1 && !StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())){//逾期状态  取当前时间
			calendar.setTime(new Date());
		}else{//未逾期状态取最迟还款日
			calendar.setTime(planDTO.getPaymentDateLate());
		}
		int actDay=0;
		if(extensionDay!=1){//展期天数为1天则不包含今天  展期天数不为1需要包含今天
			actDay=extensionDay-1;
		}else{
			actDay=extensionDay;
		}
		calendar.add(Calendar.DAY_OF_YEAR, actDay);
		Date paymentDateLate=calendar.getTime();
		//更新合同计划的最迟还款日
		McfeCustomerRepaymentPlanDTO updatePlan=new McfeCustomerRepaymentPlanDTO();
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>获取本地用户信息失败");
		}

		//获取应冲销的滞纳金
		BigDecimal reverseLateAmount = getReverseLateByExtension(loanId,amount,extensionDay);

		String userCode=user==null?"system":user.getUserCode();
		updatePlan.setId(planDTO.getId());
		updatePlan.setUpdatedBy(userCode);
		updatePlan.setDelqDays(0);
		updatePlan.setStatus(0);
		//设置还款计划剩余应还滞纳金信息
		//updatePlan.setLateFee(planDTO.getLateFee().subtract(reverseLateAmount));
		//设置还款计划已还滞纳金信息
		updatePlan.setLateFeeAct((planDTO.getLateFeeAct() == null ? BigDecimal.ZERO : planDTO.getLateFeeAct()).add(reverseLateAmount));
		updatePlan.setUpdatedDate(new Date());
		updatePlan.setPaymentDateLate(paymentDateLate);
		mcfeCustomerRepaymentPlanDao.updateRepaymentPlanById(updatePlan);

		//修改合同表状态和逾期天数
		McfeCustomerLoanContractDTO mcfeCustomerLoanContractDTO=new McfeCustomerLoanContractDTO();
		mcfeCustomerLoanContractDTO.setLoanId(loanId);
		mcfeCustomerLoanContractDTO.setDelqDays(0);
		mcfeCustomerLoanContractDTO.setStatus(0);//正常
		//设置合同已还滞纳金信息
		mcfeCustomerLoanContractDTO.setLateFee(contractDTO.getLateFee().add(reverseLateAmount));
		//设置合同剩余应还滞纳金信息
		mcfeCustomerLoanContractDTO.setLateFeeOs(contractDTO.getLateFeeOs().subtract(reverseLateAmount));
		mcfeCustomerLoanContractDTO.setId(contractDTO.getId());
		mcfeCustomerLoanContractDTO.setUpdatedDate(new Date());
		mcfeCustomerLoanContractDTO.setUpdatedBy(userCode);
		mcfeCustomerLoanContractDao.updateContractStatusByLoanId(mcfeCustomerLoanContractDTO);

		//分期模式时将催收记录置为催回状态
		if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())){
			overdueCollectTaskDao.urgentByLoanId(loanId);
		}
	}

	//通过展期费代扣金额和展期天数计算应冲销的滞纳金
	private BigDecimal getReverseLateByExtension(String loanId ,BigDecimal amount,int extensionDay){
		BigDecimal reverseLateAmount = BigDecimal.ZERO;

		//通过展期天数计算不包含滞纳金的展期费用
		ExtensionFunctionEnum[] extensionlist=ExtensionFunctionEnum.enums();
		BigDecimal extensionAmount = BigDecimal.ZERO;
		for(ExtensionFunctionEnum extensionFunctionEnum:extensionlist){
			if(extensionDay == extensionFunctionEnum.getDay()){
				McfeLendingProcess mcfeLendingProcess=mcfeLendingProcessDao.selectByloanIdAndStatus(loanId, "");
				extensionAmount=new BigDecimal(extensionFunctionEnum.getValue()).multiply(mcfeLendingProcess.getPrincipalAmtAct());
				break;
			}
		}
		//应冲销滞纳金=已扣款展期费-（审批核定金额*展期天数利率）
		reverseLateAmount = amount.subtract(extensionAmount);
		return reverseLateAmount;
	}


	/**
	 * 持久化冲账流水
	 */
	public int persistentFlowDetail(McfeCustomerLoanContractDTO contractDto,McfePaymentWithholdDTO paymentWithholdDTO,McfePaymentWithholdDetailDTO detailDTO) throws MarvelsBusinessException{
		// 持久化还款流水/冲销流水
		McfeRepaymentFlowDTO mcfeRepaymentFlowDto = new McfeRepaymentFlowDTO();
		mcfeRepaymentFlowDto.setAmountAct(detailDTO.getAmountAct());
		mcfeRepaymentFlowDto.setCustName(contractDto.getCustName());
		mcfeRepaymentFlowDto.setCustCardNo(contractDto.getCustCardNo());
		mcfeRepaymentFlowDto.setStatus("0");//冲账状态 0未冲账；1冲账中; 2代扣成功; 3 反冲销
		mcfeRepaymentFlowDto.setLoanId(contractDto.getLoanId());
		mcfeRepaymentFlowDto.setBankCardNo(paymentWithholdDTO.getBankCardNo());
		mcfeRepaymentFlowDto.setBankName(paymentWithholdDTO.getBankName());
		mcfeRepaymentFlowDto.setBankHeadLink(contractDto.getPaymentBankHead());
		mcfeRepaymentFlowDto.setFundCode(contractDto.getFundCode());
		mcfeRepaymentFlowDto.setFundName(contractDto.getFundName());
		mcfeRepaymentFlowDto.setProductType(contractDto.getProductType());
		mcfeRepaymentFlowDto.setProductTypeName(contractDto.getProductTypeName());
		mcfeRepaymentFlowDto.setProductCode(contractDto.getProductCode());
		mcfeRepaymentFlowDto.setProductName(contractDto.getProductName());
		mcfeRepaymentFlowDto.setChannelCode(contractDto.getChannelCode());
		mcfeRepaymentFlowDto.setChannelName(contractDto.getChannelName());
		mcfeRepaymentFlowDto.setAmount(detailDTO.getAmount());
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>获取本地用户信息失败");
		}
		String userCode=user==null?"system":user.getUserCode();
		mcfeRepaymentFlowDto.setCreatedBy(userCode);
		mcfeRepaymentFlowDto.setUpdatedBy(userCode);
		mcfeRepaymentFlowDto.setCreatedDate(new Date());
		mcfeRepaymentFlowDto.setUpdatedDate(new Date());
		mcfeRepaymentFlowDto.setMobile(contractDto.getMobile());
		mcfeRepaymentFlowDto.setRepayStyle(paymentWithholdDTO.getRepayStyle()+"");
		if(StringUtils.isNotEmpty(paymentWithholdDTO.getReqChannel())){
			mcfeRepaymentFlowDto.setReqChannel(paymentWithholdDTO.getReqChannel());
		}
		mcfeRepaymentFlowDto.setResChannel(detailDTO.getResChannel());
		mcfeRepaymentFlowDto.setRtnOrderNo(detailDTO.getRtnOrderNo());
		mcfeRepaymentFlowDto.setRtnResponseCode(detailDTO.getRtnResponseCode());
		mcfeRepaymentFlowDto.setRtnResponseDate(new Date());
		mcfeRepaymentFlowDto.setRtnResponseMsg(detailDTO.getRtnResponseMsg());
		mcfeRepaymentFlowDto.setPayType(paymentWithholdDTO.getFlowPayType());
		mcfeRepaymentFlowDto.setTranctionDate(new Date());
		mcfeRepaymentFlowDto.setTransctionSeq(detailDTO.getTransctionSeq());
		return mcfeRepaymentFlowDao.insertSelective(mcfeRepaymentFlowDto);
	}

	/**
	 *
	* @Title: withholdPreSettleDeal
	* @Description:提前结清
	* @param paymentWithholdDTO
	* @return
	* @throws MarvelsBusinessException
	* @author 李瑶
	* @date 2018年10月20日 下午2:05:28
	 */
	@Override
	public PaymentResponse withholdPreSettleDeal(McfePaymentWithholdDTO paymentWithholdDTO)
			throws MarvelsBusinessException {
		// 提前结清
		String loanId = paymentWithholdDTO.getLoanId();
		if (StringUtils.isEmpty(loanId)) {
			throw new MarvelsBusinessException("loanId不能为空");
		}
		if (paymentWithholdDTO.getAmount() == null || paymentWithholdDTO.getAmount().compareTo(BigDecimal.ZERO) < 1) {
			throw new MarvelsBusinessException("金额必须大于0,loanId:"+loanId);
		}
//		if (StringUtils.isEmpty(paymentWithholdDTO.getBankHeadLink())) {
//			throw new MarvelsBusinessException("支行不能为空");
//		}
		if (StringUtils.isEmpty(paymentWithholdDTO.getBankCardNo())) {
			throw new MarvelsBusinessException("银行卡号不能为空,loanId:"+loanId);
		}
		if (StringUtils.isEmpty(paymentWithholdDTO.getBankName())) {
			throw new MarvelsBusinessException("银行名称不能为空,loanId:"+loanId);
		}
		if (StringUtils.isEmpty(paymentWithholdDTO.getCustCardNo())) {
			throw new MarvelsBusinessException("身份证号不能为空,loanId:"+loanId);
		}
		if (StringUtils.isEmpty(paymentWithholdDTO.getTransctionSeq())) {
			throw new MarvelsBusinessException("请求编号不能为空,loanId:"+loanId);
		}
		if (StringUtils.isEmpty(paymentWithholdDTO.getRepayStyle())) {
			throw new MarvelsBusinessException("还款方式不能为空,loanId:"+loanId);
		}
		if (StringUtils.isEmpty(paymentWithholdDTO.getFlowPayType())) {
			throw new MarvelsBusinessException("还款类型不能为空,loanId:"+loanId);
		}
		// 加锁 避免重复插入数据
		String key = RedisKeyConstant.HAND_PAYMENT_WITHHOLD + loanId;
		boolean isNotLock = false;
		try {
			isNotLock = CacheUtils.isNotLock(key, loanId);
			if (isNotLock) {
				// 先将这个key设置过期时间
				CacheUtils.setExpire(key, 60);
				HandWithholdConditionDTO conditionDTO = new HandWithholdConditionDTO();
				conditionDTO.setLoanId(loanId);
				Page<HandWithholdListDTO> contractDtoList = mcfeCustomerLoanContractDao.selectWithholdApplyList(conditionDTO);
				if (null == contractDtoList || contractDtoList.size() < 1) {
					throw new MarvelsBusinessException("合同信息不存在");
				}
				HandWithholdListDTO contractDto = contractDtoList.get(0);
				if ("2".equals(contractDto.getStatus()) || "3".equals(contractDto.getStatus())
						|| "10".equals(contractDto.getStatus())) {
					throw new MarvelsBusinessException("进件不处于还款状态");
				}
				// 判断还款计划对应的进件是否有处在交易中的代扣
				McfePaymentWithholdDetailDTO detailDTO = detailDao.selectTradingByLoanId(loanId);
				if (detailDTO != null) {
					MarvelsLogUtil.getInstance().info(">>>>>>>>>>loanId:" + loanId + ",有处在交易中的代扣");
					throw new MarvelsBusinessException("存在处理中的代扣,请稍候再试");
				}
				// 判断还款计划对应的进件是否有处在正在冲账中的流水
				McfeRepaymentFlowDTO flowDTO = flowDao.selectDealingByLoanId(loanId);
				if (flowDTO != null) {
					MarvelsLogUtil.getInstance().info(">>>>>>>>>>loanId:" + loanId + ",有处在冲账中或未冲账的流水");
					throw new MarvelsBusinessException("存在未冲账的流水,请稍候再试");
				}
				String userCode = "system";
				// 插入代扣
				paymentWithholdDTO.setPayCount(1);
				paymentWithholdDTO.setStatus("2");// 代扣中
				paymentWithholdDTO.setCreatedBy(userCode);
				paymentWithholdDTO.setCreatedDate(new Date());
				paymentWithholdDTO.setUpdatedBy(userCode);
				paymentWithholdDTO.setUpdatedDate(new Date());
				if(StringUtil.isEmpty(paymentWithholdDTO.getWithholdCode())) {
					paymentWithholdDTO.setWithholdCode(paymentWithholdDTO.getTransctionSeq());
					if(StringUtil.isEmpty(paymentWithholdDTO.getWithholdCode())) {
						paymentWithholdDTO.setWithholdCode(GenerateReqNoUtils.transctionReq("DK"));
					}
				}
				int count = withholdDao.insertSelective(paymentWithholdDTO);
				if (count < 1) {
					throw new MarvelsBusinessException("持久化代扣申请失败");
				}
				BigDecimal succcessAmount = new BigDecimal("0.00");
				// 代扣明细
				String reqNo = GenerateReqNoUtils.transctionReq("TX");
				detailDTO = new McfePaymentWithholdDetailDTO();
				detailDTO.setAmount(paymentWithholdDTO.getAmount());
				detailDTO.setBankCardNo(paymentWithholdDTO.getBankCardNo());
				detailDTO.setBankHeadLink(paymentWithholdDTO.getBankHeadLink());
				detailDTO.setBankName(paymentWithholdDTO.getBankName());
				detailDTO.setChannelCode(paymentWithholdDTO.getChannelCode());
				detailDTO.setChannelName(paymentWithholdDTO.getChannelName());
				detailDTO.setCreatedBy(userCode);
				detailDTO.setCreatedDate(new Date());
				detailDTO.setCustCardNo(paymentWithholdDTO.getCustCardNo());
				detailDTO.setCustName(paymentWithholdDTO.getCustName());
				detailDTO.setFundCode(paymentWithholdDTO.getFundCode());
				detailDTO.setFundName(paymentWithholdDTO.getFundName());
				detailDTO.setLoanId(paymentWithholdDTO.getLoanId());
				detailDTO.setMobile(paymentWithholdDTO.getMobile());
				detailDTO.setPayType(String.valueOf(paymentWithholdDTO.getPayType()));
				detailDTO.setProductCode(paymentWithholdDTO.getProductCode());
				detailDTO.setProductName(paymentWithholdDTO.getProductName());
				detailDTO.setProductType(paymentWithholdDTO.getProductType());
				detailDTO.setProductTypeName(paymentWithholdDTO.getProductTypeName());
				if(StringUtils.isNotEmpty(paymentWithholdDTO.getReqChannel())){
					detailDTO.setReqChannel(paymentWithholdDTO.getReqChannel());
				}
				detailDTO.setStatus("1");// 交易中
				detailDTO.setTranctionDate(new Date());
				detailDTO.setTransctionSeq(reqNo);
				detailDTO.setUpdatedBy(userCode);
				detailDTO.setUpdatedDate(new Date());
				detailDTO.setWithholdCode(paymentWithholdDTO.getWithholdCode());
				detailDTO.setWithholdCategory(paymentWithholdDTO.getWithholdCategory());
				int detailCount = withholdDetailDao.insertSelective(detailDTO);
				if (detailCount < 1) {
					throw new MarvelsBusinessException("持久化明细代扣申请失败");
				}


				// 发起代扣
				HandleWithholePaymentDTO paymentDTO = new HandleWithholePaymentDTO();
				paymentDTO.setAmount(detailDTO.getAmount());
				paymentDTO.setBankName(detailDTO.getBankName());
				paymentDTO.setCustBankAccountNo(detailDTO.getBankCardNo());
				paymentDTO.setCustBankAcctType("1");
				paymentDTO.setCustBindPhoneNo(detailDTO.getMobile());
				paymentDTO.setCustId(detailDTO.getCustCardNo());
				paymentDTO.setCustName(detailDTO.getCustName());
				paymentDTO.setFundSource(detailDTO.getFundCode());
				paymentDTO.setLoanId(detailDTO.getLoanId());
				paymentDTO.setMerchantTreatyNo(detailDTO.getLoanId());
				if (StringUtils.isNotEmpty(detailDTO.getReqChannel())) {
					paymentDTO.setPaymentChannel(detailDTO.getReqChannel());
				}
				paymentDTO.setRemark("提前结清代扣");
				paymentDTO.setReqNo(detailDTO.getTransctionSeq());
				PaymentResponse paymentResponse = null;
				MarvelsLogUtil.getInstance().info(">>>>>>>>提前结清代扣发起代扣交易请求参数:" + JSONObject.fromObject(paymentDTO));
				try {
					paymentResponse = withholdPayment(paymentDTO);
				} catch (Exception e) {
					MarvelsLogUtil.getInstance().error(">>>>>>>>提前结清代扣发起代扣交易异常:", e);
				}
				MarvelsLogUtil.getInstance().info(">>>>>>>>提前结清代扣发起代扣交易返回参数:" + JSONObject.fromObject(paymentResponse));
				String status = "";// ；1交易中; 2代扣成功 9代扣失败
				String rtnOrderNo = "";// 第三方返回订单号
				String rtnResponseCode = "";// 扣款返回码
				String rtnResponseMsg = "";// 扣款返回信息
				BigDecimal amountAct = new BigDecimal("0");// 实际成功金额
				String resChannel = null;
				if (null == paymentResponse) {
					status = "1";
					rtnResponseMsg = "返回信息为空";
				} else {
					resChannel = paymentResponse.getChannel();
					rtnResponseMsg = paymentResponse.getMsg();
					rtnOrderNo = paymentResponse.getOrderNumber();
					rtnResponseCode = paymentResponse.getCode();
					if ("0".equals(paymentResponse.getCode())) {// 成功
						status = "2";
						amountAct = paymentDTO.getAmount();
					}else if(MarvelsConstant.FAILED.equals(paymentResponse.getCode())){//失败
						status = "9";
					}else {// 其余做处理中处理
						status = "1";
					}
					// 001 快付通（云科贷） ,002 宝付（云科贷） 003 宝付（口袋） 004 宝付（渤海） 005 支付宝
					// 006 运营

				}
				// 更新代扣流水
				McfePaymentWithholdDetailDTO detailDTOUpdate = new McfePaymentWithholdDetailDTO();
				detailDTOUpdate.setId(detailDTO.getId());
				detailDTOUpdate.setLoanId(detailDTO.getLoanId());
				detailDTOUpdate.setUpdatedBy(userCode);
				detailDTOUpdate.setUpdatedDate(new Date());
				detailDTOUpdate.setAmountAct(amountAct);
				detailDTOUpdate.setStatus(status);// ；1交易中; 2代扣成功 9代扣失败
				detailDTOUpdate.setRtnOrderNo(rtnOrderNo);
				detailDTOUpdate.setResChannel(resChannel);
				detailDTOUpdate.setRtnResponseDate(new Date());
				detailDTOUpdate.setRtnResponseCode(rtnResponseCode);// 扣款返回码
				detailDTOUpdate.setRtnResponseMsg(rtnResponseMsg);// 扣款返回信息
				int updateCount = withholdDetailDao.updateByPrimaryKeySelective(detailDTOUpdate);
				if ("2".equals(status)) {// 成功
					// 持久化还款流水/冲销流水
					McfeRepaymentFlowDTO mcfeRepaymentFlowDto = new McfeRepaymentFlowDTO();
					mcfeRepaymentFlowDto.setAmountAct(detailDTO.getAmountAct());
					mcfeRepaymentFlowDto.setCustName(detailDTO.getCustName());
					mcfeRepaymentFlowDto.setCustCardNo(detailDTO.getCustCardNo());
					mcfeRepaymentFlowDto.setStatus("0");//冲账状态 0未冲账；1冲账中; 2代扣成功; 3 反冲销
					mcfeRepaymentFlowDto.setLoanId(detailDTO.getLoanId());
					mcfeRepaymentFlowDto.setBankCardNo(detailDTO.getBankCardNo());
					mcfeRepaymentFlowDto.setBankName(detailDTO.getBankName());
					mcfeRepaymentFlowDto.setBankHeadLink(detailDTO.getBankHeadLink());
					mcfeRepaymentFlowDto.setFundCode(detailDTO.getFundCode());
					mcfeRepaymentFlowDto.setFundName(detailDTO.getFundName());
					mcfeRepaymentFlowDto.setProductType(detailDTO.getProductType());
					mcfeRepaymentFlowDto.setProductTypeName(detailDTO.getProductTypeName());
					mcfeRepaymentFlowDto.setProductCode(detailDTO.getProductCode());
					mcfeRepaymentFlowDto.setProductName(detailDTO.getProductName());
					mcfeRepaymentFlowDto.setChannelCode(detailDTO.getChannelCode());
					mcfeRepaymentFlowDto.setChannelName(detailDTO.getChannelName());
					mcfeRepaymentFlowDto.setCreatedBy(userCode);
					mcfeRepaymentFlowDto.setUpdatedBy(userCode);
					mcfeRepaymentFlowDto.setCreatedDate(new Date());
					mcfeRepaymentFlowDto.setUpdatedDate(new Date());
					mcfeRepaymentFlowDto.setMobile(detailDTO.getMobile());
					mcfeRepaymentFlowDto.setRepayStyle(detailDTO.getPayType());
					if (StringUtils.isNotEmpty(detailDTO.getReqChannel())) {
						mcfeRepaymentFlowDto.setReqChannel(detailDTO.getReqChannel());
					}
					mcfeRepaymentFlowDto.setResChannel(resChannel);
					mcfeRepaymentFlowDto.setRtnOrderNo(rtnOrderNo);
					mcfeRepaymentFlowDto.setRtnResponseCode(rtnResponseCode);
					mcfeRepaymentFlowDto.setRtnResponseDate(new Date());
					mcfeRepaymentFlowDto.setRtnResponseMsg(rtnResponseMsg);
					if ("10".equals(detailDTO.getPayType()) || "3".equals(detailDTO.getPayType())) {
						mcfeRepaymentFlowDto.setPayType("1");
					} else {
						mcfeRepaymentFlowDto.setPayType("2");
					}
					mcfeRepaymentFlowDto.setTranctionDate(new Date());
					mcfeRepaymentFlowDto.setTransctionSeq(detailDTO.getTransctionSeq());
					mcfeRepaymentFlowDao.insertSelective(mcfeRepaymentFlowDto);
				}
				// 更新代扣总记录
				McfePaymentWithholdDTO withholdDTOUpdate = new McfePaymentWithholdDTO();
				withholdDTOUpdate.setLoanId(paymentWithholdDTO.getLoanId());
				if ("2".equals(status)) {
					withholdDTOUpdate.setStatus("1");// 代扣成功
				} else {
					withholdDTOUpdate.setStatus("2");// 处理中
				}
				withholdDTOUpdate.setAmountAct(paymentDTO.getAmount());
				withholdDTOUpdate.setUpdatedBy(userCode);
				withholdDTOUpdate.setUpdatedDate(new Date());
				withholdDao.updateByPrimaryKeySelective(withholdDTOUpdate);
				return paymentResponse;
			}
			return null;
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",提前结清-代扣还款-审批通过异常:", e);
			throw new MarvelsBusinessException(e.getMessage());
		} finally {
			if (!CacheUtils.isNotLock(key, loanId)) {// 如果是锁住的将所释放
				CacheUtils.del(key);
			}
		}
	}


	@Override
	public void withholdSuccess(McfeCustomerLoanContractDTO contractDto, McfePaymentWithholdDTO paymentWithholdDTO,
			McfePaymentWithholdDetailDTO detailDTO) throws MarvelsBusinessException {
		String withholdCategory=paymentWithholdDTO.getWithholdCategory();
		if(withholdCategory.equals("1") || StringUtils.isEmpty(withholdCategory)){//如果是扣还款金额 则持久化冲账流水
			persistentFlowDetail(contractDto,paymentWithholdDTO,detailDTO);
		}else if(withholdCategory.equals("2")){//扣展期费成功逻辑
			extensionwithholdeSuccess(paymentWithholdDTO);
		}
	}

	public static void main(String[] args) {
		BigDecimal aa = BigDecimal.valueOf(300.005);
		System.out.println(aa.toString());
		System.out.println(aa.setScale(2, BigDecimal.ROUND_HALF_UP));
	}

	@Override
	public McfeCustomerLoanContractDTO synchronizedBankCard(McfeCustomerLoanContractDTO contractDto,String channel){
		String custCardNo=contractDto.getCustCardNo();
		String loanId=contractDto.getLoanId();
		if(StringUtils.isEmpty(custCardNo)){
			return contractDto;
		}
		if(StringUtils.isEmpty(loanId)){
			return contractDto;
		}
		try {
			if(StringUtils.isEmpty(channel)){
				channel = ServerProperties.getValue(configPropertiesPath, "common.properties", "payment_channel");
			}
			//查询当前支付通道的绑卡记录的最后一条
			McfePaymentUserBindCard mcamPaymentUserBindCards=new McfePaymentUserBindCard();
			mcamPaymentUserBindCards.setIdno(custCardNo);
			mcamPaymentUserBindCards.setChannel(channel);
			mcamPaymentUserBindCards = mcamPaymentUserBindCardMapper.selectBindCard(mcamPaymentUserBindCards);
			if(mcamPaymentUserBindCards!=null){//绑卡记录不为空 同步银行卡信息
				//银行卡不一致同步还款计划 合同的银行卡信息
				if(!contractDto.getPaymentAcctNo().equals(mcamPaymentUserBindCards.getBankCardNo())){
					//更新合同信息
					McfeCustomerLoanContractDTO loanContractDTO=new McfeCustomerLoanContractDTO();
					loanContractDTO.setPaymentAcctNo(mcamPaymentUserBindCards.getBankCardNo());
					loanContractDTO.setPaymentBankName(mcamPaymentUserBindCards.getBankName());
					loanContractDTO.setMobile(mcamPaymentUserBindCards.getPhone());
					loanContractDTO.setLoanId(loanId);
					String userCode=null;
					UserDTO user = null;
					try {
						user=CacheUtils.getCacheUser();
					} catch (Exception e) {
					}
					if(user==null){
						userCode="system";
					} else{
						userCode=user.getUserCode();
					}
					loanContractDTO.setUpdatedBy(userCode);
					loanContractDTO.setUpdatedDate(new Date());
					mcfeCustomerLoanContractDao.updateContractBankInfoByLoanId(loanContractDTO);

					contractDto.setPaymentAcctNo(mcamPaymentUserBindCards.getBankCardNo());
					contractDto.setPaymentBankName(mcamPaymentUserBindCards.getBankName());
					contractDto.setMobile(mcamPaymentUserBindCards.getPhone());
				}
			}

		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>loanId:"+loanId+"同步合同银行卡信息异常:",e);
		}
		return contractDto;
	}

}
